home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
wgt
/
wgtrun
/
run4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-21
|
8KB
|
391 lines
#include <wgt5.h>
#include <math.h>
/*
run4.c
Same as run3.c, only with timer controlled animation.
Try running it on different speed computers, or turn your turbo off.
*/
#define TICKS(hz) ((int)(1193182L/(hz)))
unsigned char shadowtable[256]; /* Shadow table */
unsigned char *transparency_table; /* a 65536 byte table,
allocated dynamically */
color pal[256]; /* The palette used for every graphic image */
block sprites[200]; /* Array of images for the running robot */
block background; /* Holds the background scrolling image */
block work; /* Page for constructing each frame */
int animation_count; /* Used for animation timing */
int movement_multiplier;/* Number of times to move objects, ground, etc */
/* A structure which holds the scrolling values for each horizontal line */
typedef struct
{
int x; /* Current x value, shifted by 8 */
int increment; /* fixed point increment */
} line_scroll;
line_scroll lines[80]; /* 80 scrolling lines along the ground */
/* A simple sprite structure */
typedef struct
{
int x;
int y;
int anm; /* Sprite number */
} sprite;
sprite people[5];
int backx = 0; /* X value for the scrolling rocks */
int backinc; /* X increment for scrolling rocks */
/* Loads the graphics files, and allocates buffers */
void load_graphics (void)
{
work = wallocblock (320, 200);
/* Allocate a work buffer */
wloadsprites (pal, "run.spr", sprites, 0, 199);
background = wloadgif ("street.gif", pal);
wsetpalette (0, 255, pal);
transparency_table = (unsigned char *)malloc (65536);
}
/* Frees the buffers and sprites */
void free_graphics (void)
{
free (transparency_table);
wfreesprites (sprites, 0, 199);
wfreeblock (background);
wfreeblock (work);
}
/* Set up the initial scrolling values */
void init_lines (void)
{
int i;
int inc;
inc = 128; /* slowest scrolling speed (128/256 of a pixel */
backx = 0; /* rocks x value */
backinc = inc; /* rocks same speed as the ground */
for (i = 0; i < 80; i++)
{
lines[i].x = 0; /* clear out the x value */
lines[i].increment = inc; /* set the scroll speed */
inc += 32; /* Make the next row move faster */
}
}
/* Construct the background image */
void animate_lines (void)
{
block source1, source2;
block dest1, dest2;
block origsource, origdest;
int i;
int x;
int mult;
wcopyscreen (0, 0, 319, 51, background, 0, 0, work);
/* Draw the moon stationary */
/* Scroll the rocks */
for (mult = 0; mult <= movement_multiplier; mult++)
{
backx += backinc;
if (backx >= 81920) /* 81920 is 320 << 8 */
backx -= 81920;
}
x = backx >> 8;
/* Copy the rocks */
wcopyscreen (x, 52, 319, 119, background, 0, 52, work);
if (x > 0)
wcopyscreen (0, 52, x-1, 119, background, 320 - x, 52, work);
origdest = abuf + 120 * 320; /* First row to copy */
origsource = background + 120 * 320; /* First row to copy */
for (i = 0; i < 80; i++)
{
/* Scroll this line */
for (mult = 0; mult <= movement_multiplier; mult++)
{
lines[i].x += lines[i].increment;
if (lines[i].x >= 81920) /* 81920 is 320 << 8, wraps scroll around */
lines[i].x -= 81920;
}
x = lines[i].x >> 8;
/* Get the x coord */
dest1 = origdest + i * 320;
dest2 = dest1 + (319 - x);
source1 = origsource + i * 320;
source2 = source1 + x;
/* Copy the line in two steps */
memcpy (dest1, source2, 320 - x);
if (x > 0)
memcpy (dest2, source1, x + 1);
}
}
/* Animates and displays the running man */
void animate_man (void)
{
int mult;
for (mult = 0; mult <= movement_multiplier; mult++)
{
people[0].anm++;
if (people[0].anm > 29)
people[0].anm = 0;
}
wputblock_shade (people[0].x, 158, sprites[people[0].anm+30],
shadowtable, 1);
wputblock_shade (people[0].x, people[0].y, sprites[people[0].anm],
transparency_table, 2);
}
void wcreate_shadow_table (color *palette)
{
float fr, fg, fb;
long ir, ig, ib;
long absr, absg, absb;
int r,g,b;
short col;
short findcol;
unsigned long lowest;
unsigned char bestfit;
unsigned long coldif;
for (col = 0; col < 256; col++)
{
fr = (float)palette[col].r * (0.5);
fg = (float)palette[col].g * (0.5);
fb = (float)palette[col].b * (0.5);
ir = fr;
ig = fg;
ib = fb;
lowest = 655350;
for (findcol = 0; findcol < 256; findcol++)
{
absr = abs ( (long)palette[findcol].r - ir);
absg = abs ( (long)palette[findcol].g - ig);
absb = abs ( (long)palette[findcol].b - ib);
coldif = absr + absg + absb;
if ((coldif < lowest) && (findcol != col))
{
lowest = coldif;
bestfit = findcol;
}
}
shadowtable[col] = bestfit;
}
}
void wcreate_transparency_table (color *pal)
{
float lightlevel1;
float lightlevel2;
float fr, fg, fb;
float fr2, fg2, fb2;
long ir, ig, ib;
long absr, absg, absb;
short col, col2;
short findcol;
unsigned long lowest;
unsigned char bestfit;
unsigned long coldif;
lightlevel1 = 0.5; /* Percent of color 1 */
lightlevel2 = 0.5; /* Percent of color 2 */
/* Lightlevel1 and lightlevel2 must total to 1 */
/* Transparency is created by taking two colors, multiplying the
RGB values by a percentage, and adding the RGB values together. The
new color will contain a little bit of each oringal color. */
/* For each of the 256 colors, we can mix with any other color, therefore
we need a 256x256 table. */
wtextcolor (15);
wtexttransparent (TEXTFGBG);
wgtprintf (0, 0, NULL, "Making transparency table...", col2);
for (col2 = 0; col2 < 256; col2++)
{
for (col = 0; col < 256; col++)
{
fr = (float)pal[col].r * lightlevel1;
fg = (float)pal[col].g * lightlevel1;
fb = (float)pal[col].b * lightlevel1;
fr2= (float)pal[col2].r * lightlevel2;
fg2= (float)pal[col2].g * lightlevel2;
fb2= (float)pal[col2].b * lightlevel2;
ir = (fr + fr2);
ig = (fg + fg2);
ib = (fb + fb2);
lowest = 655350;
for (findcol = 0; findcol < 256; findcol++)
{
absr = abs ( (long)pal[findcol].r - ir) * 30;
absg = abs ( (long)pal[findcol].g - ig) * 59;
absb = abs ( (long)pal[findcol].b - ib) * 11;
coldif = sqrt(absr*absr + absg*absg + absb*absb);
if (coldif < lowest)
{
lowest = coldif;
bestfit = findcol;
}
}
transparency_table[col2 * 256L + col] = bestfit;
}
wgtprintf (0, 8, NULL, "Color %03hi", col2);
}
}
void animation_timer (void)
{
animation_count++;
}
int load_table (char *filename, block table, int size)
{
FILE *in;
in = fopen (filename, "rb");
if (in == NULL)
return 0;
fread (table, size, 1, in);
fclose (in);
return 1;
}
void save_table (char *filename, block table, int size)
{
FILE *out;
out = fopen (filename, "wb");
fwrite (table, size, 1, out);
fclose (out);
}
void main (void)
{
vga256 ();
load_graphics ();
init_lines ();
/* Set the position of the running man */
people[0].x = 120;
people[0].y = 50;
people[0].anm = 0;
wcreate_shadow_table (pal);
if (!load_table ("trans.dat", transparency_table, 65536))
{
wcreate_transparency_table (pal);
save_table ("trans.dat", transparency_table, 65536);
}
animation_count = 0;
winittimer ();
wstarttimer (animation_timer, TICKS (60));
do {
wsetscreen (work);
movement_multiplier = animation_count;
if (movement_multiplier > 1)
{
/* Since our running animation is 30 frames, I'll make this animation
update every other frame (half of 60).
/* If animation_count is odd, keep the odd count */
animation_count = movement_multiplier % 2;
movement_multiplier /= 2;
/* Halve the animation speed */
animate_lines ();
animate_man ();
wnormscreen ();
wputblock (0, 0, work, 0);
}
} while (!kbhit ());
wstoptimer ();
wdonetimer ();
free_graphics ();
wsetmode (3);
}